package game;

import java.awt.Font;
import java.awt.FontFormatException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.vecmath.Vector3f;
import org.lwjgl.input.Mouse;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.dynamics.RigidBody;
import AGFX.F3D.F3D;
import AGFX.F3D.Camera.TF3D_Camera;
import AGFX.F3D.Font.TF3D_Font_TTF;
import AGFX.F3D.Light.TF3D_Light;
import AGFX.F3D.Model.TF3D_Model;

/**
 * @author Baskervil
 *
 */
public class TGame {
	
	public TF3D_Camera Camera;
	public TCard model;
	public TF3D_Model carpet;
	public RigidBody body;
	public TCard obj1;
	public TCard obj2;
	public ArrayList<TCard> sb = new ArrayList<TCard>();
	public int row = 0;
	public int column = 0;
	public int step = 0;
	public float x_offset = -5.2f;
	public float y_offset = -2.1f;
	public float distance = 1.5f;
	public float xp = 0;
	public float yp = 0;
	public float xPos = 0;
	public float yPos = 0;
	public Vector3f up_impulse = new Vector3f(0f,0.2f,0f);
	public Vector3f torque_impulse = new Vector3f(0.15f,0f,0f);
	public boolean switchit = false; 
	public boolean check_all = true;
	public Date start_time = null;
	public Date end_time = new Date();
	public Calendar cal = new GregorianCalendar(); 
	public TF3D_Font_TTF ttf_pex;
	public Font          font_pex;

	// constructor
	public TGame() {
		F3D.Worlds.CreateWorld("GAME");
		F3D.Worlds.SetWorld("GAME");

		F3D.Viewport.Clear(0f, 0f, 0f, 0f);
		
		this.Camera = new TF3D_Camera("Game_Camera");
		this.Camera.SetPosition(0.0f, 8f,4f);
		this.Camera.SetRotation(60f, 0, 0);
		this.Camera.ctype = F3D.CAMERA_TYPE_FPS;
		
		F3D.Cameras.Add(this.Camera);
		F3D.Worlds.SetCamera(this.Camera);
	
		
		// Add light to scene
		TF3D_Light light = new TF3D_Light("light_1", 0);
		light.SetPosition(0f, 3f, 3f);
		light.spot_constant_att = 1f;
		light.Enable();		
		
		
		F3D.Meshes.Add("abstract::table.a3da");
		F3D.Meshes.Add("abstract::zeton.a3da");
		F3D.Meshes.Add("abstract::carpet.a3da");
		F3D.Meshes.Add("abstract::singleplayer.a3da");
		
		
		this.model = new TCard("table");
		this.model.AssignMesh("abstract::table.a3da");
		this.model.SetRotation(90f, 0f, 180f);
		this.model.Enable();
		this.model.CreateRigidBody(F3D.BULLET_SHAPE_BOX, 0f);
		
		this.carpet = new TF3D_Model("carpet");
		this.carpet.AssignMesh("abstract::carpet.a3da");
		this.carpet.SetPosition(0f, -3f, 2f);
		this.carpet.SetRotation(-90, 0, 0);
		
		try
		{
			File f = new File("media/ttf/FiveFingerDiscount.ttf");
			FileInputStream in = new FileInputStream(f);
			font_pex = Font.createFont(Font.TRUETYPE_FONT, in);
			font_pex = font_pex.deriveFont(36f);
			
		} catch (FontFormatException e)
		{
			
			e.printStackTrace();
		} catch (IOException e)
		{
			
			e.printStackTrace();
		}

		this.ttf_pex = new TF3D_Font_TTF(font_pex, true);
		
	}
	
	public float px(int percento){
		return (F3D.Config.r_display_width/100)*percento;
	}

	public float py(int percento){
		return (F3D.Config.r_display_height/100)*percento;
	}
	
	public void createGame(int row, int column) {

		for (int i = 0; i < (row * column) / 2; i++) {
			this.obj1 = new TCard("zeton"+i);
			this.obj2 = new TCard("zeton"+i);
			this.obj1.AssignMesh("abstract::zeton.a3da");
			this.obj2.AssignMesh("abstract::zeton.a3da");
			this.obj1.Enable();
			this.obj2.Enable();
			this.obj1.SetScale(0.6f, 0.6f, 0.6f);
			this.obj2.SetScale(0.6f, 0.6f, 0.6f);
			this.obj1.SetRotation(-90f, 0f, 180f);
			this.obj2.SetRotation(-90f, 0f, 180f);	
			this.obj1.setType(i);
			this.obj2.setType(i);
			this.obj1.ChangeSurface("lic", this.obj1.getType());
			this.obj2.ChangeSurface("lic", this.obj2.getType());
			this.obj1.ChangeSurface("veza", "lic");
			this.obj2.ChangeSurface("veza", "lic");
			this.sb.add(this.obj1);
			this.sb.add(this.obj2);
			this.check_all = true;
			
		}

		Collections.shuffle(this.sb);

		// change positions
		for (int k = 0; k < this.sb.size(); k++) {
			this.xp += this.distance ;
	
			this.sb.get(k).setX(this.xPos);
			this.sb.get(k).setY(this.yPos);
			this.sb.get(k).SetPosition(this.xp+this.x_offset, 1f, this.yp+this.y_offset);
			this.sb.get(k).CreateRigidBody(F3D.BULLET_SHAPE_CYLINDER_Z, 0.1f);
			this.sb.get(k).PhysicObject.RigidBody.setActivationState(CollisionObject.DISABLE_DEACTIVATION);
			this.xPos++;
			if (this.xp > column+this.distance) {
				this.xp = 0;
				this.xPos = 0;
				this.yPos++;
				this.yp += this.distance;
			}		
		}
	}
	
	public void flip(float pX, float pY) {
		
		if (this.step < 2) {
			this.step++;
			for (int i = 0; i < this.sb.size(); i++) {
				if (this.sb.get(i).getX() == pX & this.sb.get(i).getY() == pY & this.sb.get(i).getSide() == 0) {
					this.sb.get(i).setSide(1);
					this.sb.get(i).ChangeSurface("lic", this.sb.get(i).getType());
					this.sb.get(i).PhysicObject.RigidBody.applyCentralImpulse(this.up_impulse);
					//this.sb.get(i).PhysicObject.RigidBody.applyTorqueImpulse(this.torque_impulse);
				}
			}
			checkPair();
		} else {
			checkPair();
			for (int j = 0; j < this.sb.size(); j++) {
				if (this.sb.get(j).getSide() == 1) {
					this.sb.get(j).setSide(0);
					this.sb.get(j).ChangeSurface( this.sb.get(j).getType(),"lic");
					this.sb.get(j).PhysicObject.RigidBody.applyCentralImpulse(this.up_impulse);
					//this.sb.get(j).PhysicObject.RigidBody.applyTorqueImpulse(this.torque_impulse);
				}
				if (this.sb.get(j).getX() == pX & this.sb.get(j).getY() == pY & this.sb.get(j).getSide() == 0) {
					this.sb.get(j).setSide(1);
					this.sb.get(j).ChangeSurface("lic", this.sb.get(j).getType());
					this.sb.get(j).PhysicObject.RigidBody.applyCentralImpulse(this.up_impulse);
					//this.sb.get(j).PhysicObject.RigidBody.applyTorqueImpulse(this.torque_impulse);
				}
			}
			this.step = 1;
		}
		check_end();
	}
	
	public void checkPair()
	{
		int num = 0;
		int fm = 0;
		int sm = 0;
		String fms = "1";
		String sms = "2";
		
		for (int i = 0; i < this.sb.size(); i++) {
			if (this.sb.get(i).getSide()==1 & num == 0)
			{
				num = num +1;
				fm = i;
				fms = this.sb.get(i).getType();
				continue;
			}
			if (this.sb.get(i).getSide()==1 & num == 1)
			{
				num = num +1;
				sm = i;
				sms = this.sb.get(i).getType();
			}
			if (fms == sms)
			{
				this.sb.get(sm).setSide(3);
				this.sb.get(fm).setSide(3);
				this.sb.get(sm).PhysicObject.RigidBody.applyCentralImpulse(new Vector3f(0f,0.8f,0.3f));
				this.sb.get(fm).PhysicObject.RigidBody.applyCentralImpulse(new Vector3f(0f,0.8f,0.3f));
				this.sb.get(sm).PhysicObject.RigidBody.applyTorqueImpulse(this.torque_impulse);
				this.sb.get(fm).PhysicObject.RigidBody.applyTorqueImpulse(this.torque_impulse);	
			}
		}
	}

	public void check_end(){
		boolean all = false;
		for (int k = 0; k < this.sb.size(); k++) {
			if (this.sb.get(k)!= null){
				if (this.sb.get(k).getSide() < 3) {
					all = true;
				}
			}	
		}
		this.check_all = all;
		if (this.check_all == false){
			this.start_time = null;
		}
	}
	
	public void printTimer(){
		this.ttf_pex.drawString((float) F3D.Config.r_display_width-267,10.0f, "",1f,1f);
		if (this.check_all == false){
			this.ttf_pex.drawString((float) F3D.Config.r_display_width/2,10.0f, ""+String.format("Final time %1$tM %1$tS",this.cal),1f,1f,1);
		} else {
			if (this.start_time != null){
				long cas = new Date().getTime() - this.start_time.getTime() ;
				this.end_time.setTime(cas);
				this.cal.setTime(this.end_time);
			}
			this.ttf_pex.drawString((float) F3D.Config.r_display_width/2,10.0f, ""+String.format("Time %1$tM %1$tS",this.cal),1f,1f,2);
			
		}
	}
	
	public void pickIt(){
		if (Mouse.isInsideWindow())
		{
    		if (Mouse.isButtonDown(0))
    		{
    			if (this.switchit == false){
    				this.body = F3D.Pick.Mouse(Mouse.getX(),Mouse.getY());
    				if (this.body != null) 
    				{
    						TCard pb = (TCard) this.body.getUserPointer();
    						for (int k = 0; k < this.sb.size(); k++) {
    							if (pb.GetName()==this.sb.get(k).name){
    								this.flip(pb.getX(),pb.getY());
    							}
    						}
    				}
    			}
    			this.switchit = true;
    			
    		}else{
    			this.switchit = false;
    		}
    	}
	}
	
	public void restartGame(){
		if (this.start_time == null){
			this.row = 0;
			this.column = 0;
			this.step = 0;
			this.x_offset = -5.2f;
			this.y_offset = -2.1f;
			this.distance = 1.5f;
			this.xp = 0;
			this.yp = 0;
			this.xPos = 0;
			this.yPos = 0;
			this.switchit = false; 
			this.check_all = true;
			this.start_time = null;
			this.end_time = new Date();	
			for (int i = 0; i < this.sb.size(); i++) {
				for (int j = 0; j < F3D.Worlds.items.get(0).entities.size(); j++) {
					F3D.Worlds.items.get(0).entities.remove(this.sb.get(i));
				}
				this.sb.get(i).Destroy();
			}
			this.sb.clear();
			createGame(3,4);// row,column
			this.start_time = new Date();
			F3D.Log.info("game", "start");
		}
	}

	public void destroyGame(){
			this.obj1 = null;
			this.obj2 = null;
			this.row = 0;
			this.column = 0;
			this.step = 0;
			this.x_offset = -5.2f;
			this.y_offset = -2.1f;
			this.distance = 1.5f;
			this.xp = 0;
			this.yp = 0;
			this.xPos = 0;
			this.yPos = 0;
			this.switchit = false; 
			this.check_all = true;
			this.start_time = null;
			this.end_time = new Date();

			for (int i = 0; i < this.sb.size(); i++) {
				for (int j = 0; j < F3D.Worlds.items.get(0).entities.size(); j++) {
					F3D.Worlds.items.get(0).entities.remove(this.sb.get(i));
				}
				this.sb.get(i).Destroy();
			}
			this.sb.clear();
		
	}
}
